using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using HarmonyLib;

namespace TheWorldOfKongfuEasyMod;

/// <summary>
/// 修复临安劫狱死档的bug
/// </summary>
[HarmonyPatch(typeof(MapController))]
[HarmonyPatch("DoAutoAction")]
public static class Patch_MapController_DoAutoAction
{
    public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
    {
        var codeMatcher = new CodeMatcher(instructions, generator);
        codeMatcher.MatchForward(true,
            new CodeMatch(OpCodes.Ldloc_0),
            new CodeMatch(OpCodes.Ldfld),
            new CodeMatch(OpCodes.Ldc_I4_0),
            new CodeMatch(OpCodes.Ldelem_Ref),
            new CodeMatch(OpCodes.Ldstr, "SETSKIN"),
            new CodeMatch(OpCodes.Call),
            new CodeMatch(OpCodes.Brfalse)
        );
        if (!codeMatcher.IsValid)
        {
            throw new InvalidOperationException("Can't find if(act[0] == \"SETSKIN\"");
        }

        codeMatcher.Advance(1);
        var  pos1 = codeMatcher.Pos;
        codeMatcher.MatchForward(true,
            new CodeMatch(OpCodes.Ldarg_0),
            new CodeMatch(OpCodes.Ldarg_1),
            new CodeMatch(OpCodes.Call),
            new CodeMatch(OpCodes.Ret)
        );
        if (!codeMatcher.IsValid)
        {
            throw new InvalidOperationException("Can't find return");
        }
        var  pos2 = codeMatcher.Pos-1;
        codeMatcher.RemoveInstructionsInRange(pos1, pos2);
        codeMatcher.Advance(-codeMatcher.Pos + pos1);
        codeMatcher.InsertAndAdvance(
            new CodeInstruction(OpCodes.Ldarg_0).WithLabels(codeMatcher.Instruction.labels),
            new CodeInstruction(OpCodes.Ldarg_1),
            new CodeInstruction(OpCodes.Call, typeof(Patch_MapController_DoAutoAction).GetMethod("Do", BindingFlags.Static | BindingFlags.NonPublic))
        );
        return codeMatcher.Instructions();
    }

    static void Do(MapController mapController, MapController.Event _event)
    {
        string[] act = _event.evdata.action.Split('|');
        string[] array11 = act[2].Split('&');
        if (act[1] == "PLAYER")
        {
            mapController.player.charadata.m_DefaultPrefab = mapController.player.charadata.m_Prefab;
            mapController.player.charadata.m_DefaultBattleIcon = mapController.player.charadata.m_BattleIcon;
            mapController.player.charadata.m_Prefab = array11[0];
            mapController.player.charadata.m_BattleIcon = array11[1];
        }
        else
        {
            if (act[1] == "TEAM")
            {
                if ("DEFAULT".Equals(array11[0]))
                {
                    mapController.player.charadata.m_Prefab = mapController.player.charadata.m_DefaultPrefab;
                    mapController.player.charadata.m_BattleIcon = mapController.player.charadata.m_DefaultBattleIcon;
                    using (List<string>.Enumerator enumerator5 = SharedData.Instance(false).FollowList.GetEnumerator())
                    {
                        while (enumerator5.MoveNext())
                        {
                            string text35 = enumerator5.Current;
                            if (!"1186".Equals(text35))
                            {
                                CharaData charaData7 = SharedData.Instance(false).GetCharaData(text35);
                                if (charaData7 != null)
                                {
                                    charaData7.m_Prefab = charaData7.m_DefaultPrefab;
                                    charaData7.m_BattleIcon = charaData7.m_DefaultBattleIcon;
                                }
                                else
                                {
                                    global::UnityEngine.Debug.LogWarning("[DEFAULT] Can NOT find follow charaid[" + act[1] + "]");
                                }
                            }
                        }

                        goto IL_47BA;
                    }
                }

                mapController.player.charadata.m_DefaultPrefab = mapController.player.charadata.m_Prefab;
                mapController.player.charadata.m_DefaultBattleIcon = mapController.player.charadata.m_BattleIcon;
                mapController.player.charadata.m_Prefab = array11[0];
                mapController.player.charadata.m_BattleIcon = array11[1];
                using (List<string>.Enumerator enumerator5 = SharedData.Instance(false).FollowList.GetEnumerator())
                {
                    while (enumerator5.MoveNext())
                    {
                        string text36 = enumerator5.Current;
                        if (!"1186".Equals(text36))
                        {
                            CharaData charaData8 = SharedData.Instance(false).GetCharaData(text36);
                            if (charaData8 != null)
                            {
                                charaData8.m_DefaultPrefab = charaData8.m_Prefab;
                                charaData8.m_DefaultBattleIcon = charaData8.m_BattleIcon;
                                charaData8.m_Prefab = array11[0];
                                charaData8.m_BattleIcon = array11[1];
                            }
                            else
                            {
                                global::UnityEngine.Debug.LogWarning("Can NOT find follow charaid[" + act[1] + "]");
                            }
                        }
                    }

                    goto IL_47BA;
                }
            }

            CharaData charaData9 = SharedData.Instance(false).GetCharaData(act[1]);
            if (charaData9 != null)
            {
                charaData9.m_DefaultPrefab = charaData9.m_Prefab;
                charaData9.m_DefaultBattleIcon = charaData9.m_BattleIcon;
                charaData9.m_Prefab = array11[0];
                charaData9.m_BattleIcon = array11[1];
            }
            else
            {
                global::UnityEngine.Debug.LogWarning("Can NOT find charaid[" + act[1] + "]");
            }
        }

        IL_47BA:
        mapController.EventComplete(_event);
        return;
    }
}